use fxhash::FxHashMap;

use crate::gpu::arc::ArcShaderModule;

use super::values::reflection::ShaderReflection;


pub struct ShaderLib {
    pub shader_pool:FxHashMap<String,&'static str>,
    pub shader_reflection:FxHashMap<String,ShaderReflection>,
    pub shader_module:FxHashMap<String,ArcShaderModule>
}


pub struct ShaderModules {
    self_key:String, // code 
    modules:FxHashMap<u64,ArcShaderModule>
}

// impl ShaderModules {
//     pub fn new(s:&str) -> Self {
//         Self {
//             self_key:s.to_owned(),

//         }
//     }
// }

impl Default for ShaderLib {
    fn default() -> Self {
         let mut lib = Self { shader_pool:Default::default() , shader_reflection:Default::default() ,shader_module:Default::default() };

        lib.register("MathShader", include_str!("math/MathShader.wgsl"));
        lib.register("FastMathShader", include_str!("math/FastMathShader.wgsl"));


        lib.register("GlobalUniform", include_str!("core/common/GlobalUniform.wgsl"));
        lib.register("InstanceUniform", include_str!("core/common/InstanceUniform.wgsl"));
        lib.register("WorldMatrixUniform", include_str!("core/common/WorldMatrixUniform.wgsl"));
        lib.register("InlineVert", include_str!("core/inline/inline_vert.wgsl"));
        lib.register("VertexAttribute", include_str!("struct/vertex_attribute.wgsl"));
        lib.register("ColorPassFragmentOutput", include_str!("struct/ColorPassFragmentOutput.wgsl"));
        lib.register("ShadingInput", include_str!("struct/ShadingInput.wgsl"));
        lib.register("FragmentVarying", include_str!("struct/FragmentVarying.wgsl"));
        lib.register("litShader", include_str!("material/litShader.wgsl"));
        lib.register("UnLitMaterialUniformFrag", include_str!("material/uniforms/UnLitMaterialUniformFrag.wgsl"));
        
        
        lib.register("CommonVert", include_str!("base/Common_vert.wgsl"));
        lib.register("CommonFrag", include_str!("base/Common_frag.wgsl"));
        lib.register("UnLitFrag", include_str!("light/unlit_frag.wgsl"));
        

        
        lib.register("UnLit", include_str!("material/UnLit.wgsl"));
        lib.register("CanvasVertexAttribute", include_str!("canvas/canvas_vertex_attribute.wgsl"));
        lib.register("CanvasUniform", include_str!("canvas/canvas_uniform.wgsl"));
        
        //  lib.register("MathShader", MathShader);
        //  lib.register("FastMathShader", FastMathShader);
 
        //  lib.register("GlobalUniform", GlobalUniform);
        //  lib.register("WorldMatrixUniform", WorldMatrixUniform);
        //  lib.register("NormalMap_frag", NormalMap_frag);
        //  lib.register("LightingFunction_frag", LightingFunction_frag);
 
        //  lib.register("PhysicMaterialUniform_frag", PhysicMaterialUniform_frag);
        //  lib.register("UnLitMaterialUniform_frag", UnLitMaterialUniform_frag);
        //  lib.register("VideoUniform_frag", VideoUniform_frag);
 
        //  lib.register("InstanceUniform", InstanceUniform);
        //  lib.register("Inline_vert", Inline_vert);
        //  lib.register("VertexAttributes_vert", VertexAttributes);
        //  lib.register("Common_vert", Common_vert);
 
        //  lib.register("Common_frag", Common_frag);
        //  lib.register("FragmentVarying", FragmentVarying);
        //  lib.register("ColorPassFragmentOutput", ColorPassFragmentOutput);
 
        //  lib.register("LightStruct", LightStructFrag);
        //  lib.register("ShadingInput", ShadingInput);
        //  lib.register("IESProfiles_frag", IESProfiles_frag);
 
        //  lib.register("ShadowMapping_frag", ShadowMapping_frag);
 
        //  lib.register("Irradiance_frag", Irradiance_frag);
        //  lib.register("IrradianceVolumeData_frag", IrradianceVolumeData_frag);
        //  lib.register("BrdfLut_frag", BrdfLut_frag);
        //  lib.register("EnvMap_frag", EnvMap_frag);
 
        //  lib.register("ColorUtil_frag", ColorUtil);
        //  lib.register("ColorUtil", ColorUtil);
        //  lib.register("BRDF_frag", BRDF_frag);
        //  lib.register("BxDF_frag", BxDF_frag);
        //  lib.register("UnLit_frag", UnLit_frag);
        //  lib.register("Clearcoat_frag", Clearcoat_frag);
        //  lib.register("LitShader", LitShader);
        //  lib.register("PBRLItShader", PBRLItShader);
 
 
        //  lib.register("ClusterDebug_frag", ClusterDebug_frag);
        //  lib.register("BxdfDebug_frag", BxdfDebug_frag);
        //  lib.register("GenerayRandomDir", GenerayRandomDir);
         lib.register("Quad_vert_wgsl", include_str!("quad/quad_vert.wgsl"));
         lib.register("Quad_frag_wgsl", include_str!("quad/quad_frag.wgsl"));
        //  lib.register("Quad_depth2d_frag_wgsl", Quad_depth2d_frag_wgsl);
        //  lib.register("Quad_depthCube_frag_wgsl", Quad_depthCube_frag_wgsl);
        //  lib.register("sky_vs_frag_wgsl", CubeSky_Shader::sky_vs_frag_wgsl);
        //  lib.register("sky_fs_frag_wgsl", CubeSky_Shader::sky_fs_frag_wgsl);
        //  lib.register("Bloom_Brightness_frag_wgsl", Bloom_shader::Bloom_Brightness_frag_wgsl);
        //  lib.register("Bloom_blur_frag_wgsl", Bloom_shader::Bloom_blur_frag_wgsl);
        //  lib.register("Bloom_composite_frag_wgsl", Bloom_shader::Bloom_composite_frag_wgsl);

        lib

    }
}

impl ShaderLib {
    pub fn register(&mut self,name:&str , shader_source:&'static str) {
        if !self.shader_pool.contains_key(name) {
            self.shader_pool.insert(name.to_owned().to_lowercase(), shader_source);
        }
    }
    

    pub fn has_shader(&self , name:&str) -> bool {
        self.shader_pool.contains_key(&name.to_lowercase())
    }

    pub fn get_shader(&self,name:&str) -> &'static str {
        self.shader_pool.get(&name.to_lowercase()).unwrap()
        
    }

    pub fn get_shader_module(&self, name:&str) -> Option<ArcShaderModule> {
        self.shader_module.get(name).map(|s|s.clone())
    }

    pub fn set_shader_module(&mut self , name:&str,  value:ArcShaderModule) {
        self.shader_module.insert(name.to_owned(), value);
    }
}



